<template>
<div class="edit-form" element-loading-background="#f5f5f5" v-loading="loading">
    <div v-show="!getShowNodeProp" class="exp-prop">
        <div class="e-p-title">实验属性</div>
        <el-form v-if="getCurrentExpInfo" class="my-el-form scroll-bar" @submit.native.prevent>
            <el-form-item class="exp-form-item" label="实验ID"><span class="desc-tip">{{getCurrentExpInfo.experimentId}}</span></el-form-item>
            <el-form-item class="exp-form-item" label="所属项目"><span class="desc-tip">{{currentProjectInfo.projectName}}</span></el-form-item>
            <el-form-item class="exp-form-item" label="状态"><span class="desc-tip">{{getCurrentExpInfo.status?'已调度':'未调度'}}</span></el-form-item>
            <el-form-item class="exp-name-desc" label="实验名称">
                <el-input :maxlength="48" @blur="updateExp" clearable placeHolder="请输入实验名称" v-model="getCurrentExpInfo.experimentName"></el-input>
            </el-form-item>
            <el-form-item class="exp-name-desc" label="实验描述">
                <el-input :rows="5" :maxlength="100" @blur="updateExp" type="textarea" clearable placeHolder="请输入实验描述" v-model="getCurrentExpInfo.description"></el-input>
            </el-form-item>
            <el-form-item class="exp-form-item" label="修改人"><span class="desc-tip">{{getCurrentExpInfo.lastUpdateOper}}</span></el-form-item>
            <el-form-item class="exp-form-item" label="最近修改时间"><span class="desc-tip">{{getCurrentExpInfo.lastUpdateTime}}</span></el-form-item>
            <el-form-item class="exp-form-item" label="创建人"><span class="desc-tip">{{getCurrentExpInfo.createOper}}</span></el-form-item>
            <el-form-item class="exp-form-item" label="创建日期"><span class="desc-tip">{{getCurrentExpInfo.createTime}}</span></el-form-item>
        </el-form>
    </div>
    <el-tabs v-show="getShowNodeProp" type="border-card" v-model="activeName">
        <el-tab-pane :label="item.tabName" v-for="(item, i) in nodePropsInfo.tabs" :key="i" :name="`${i}`">
            <div class="scroll-bar">
                <template v-if="`${i}` === activeName && !loading">
                    <form-create :formObj="formObj[i]" :tableNames="tableNames" :formList="formList[i]" @selectField="handleSelectField" @updateControl="validateUpdateParameter"></form-create>
                </template>
            </div>
        </el-tab-pane>
    </el-tabs>
    <single-select-field v-if="single.show" :data="single" @save="handleSave"></single-select-field>
    <multiple-select-field v-if="multiple.show" :data="multiple" @save="handleSave" v-model="multipleVal"></multiple-select-field>
</div>
</template>

<script>
import {
    mapGetters,
    mapMutations
} from 'vuex'
import FormCreate from './FormCreate'
import SingleSelectField from '@/components/SingleSelectField'
import MultipleSelectField from '@/components/MultipleSelectField'

export default {
    name: 'EditForm',
    components: {
        FormCreate,
        SingleSelectField,
        MultipleSelectField
    },
    computed: {
        ...mapGetters({
            nodePropsInfo: 'common/getNodePropsInfo',
            clickNode: 'common/getClickNode',
            getNodeData: 'common/getNodeData', // 当前节点的数据
            getShowNodeProp: 'common/getShowNodeProp', // 表单节点属性和实验信息的切换
            experimentId: 'common/getExperimentId',
            projectId: 'common/getProjectId',
            getCurrentExpInfo: 'common/getCurrentExpInfo', // 当前实验信息
            currentProjectInfo: 'common/getCurrentProjectInfo' // 当前项目信息
        })
    },
    data () {
        return {
            tableNames: [],
            multipleVal: '',
            params: {},
            loading: false,
            formList: {},
            formObj: {},
            activeName: '0',
            single: {
                value: '',
                title: '选择字段',
                show: false,
                data: {}
            },
            multiple: {
                title: '选择字段',
                show: false,
                isNumber: false, // 多输入列选择框，多个列选择弹窗，只能选择数值类型的
                data: []
            }
        }
    },
    methods: {
        ...mapMutations({
            setErrorLogs: 'common/setErrorLogs',
            setNodePropsInfo: 'common/setNodePropsInfo',
            setChangedNodes: 'common/setChangedNodes',
            setUpdateExp: 'common/setUpdateExp'
        }),
        // 修改实验信息
        updateExp () {
            const {
                description,
                experimentName
            } = this.getCurrentExpInfo
            this.$post('/experiment/updateExperiment', {
                projectId: this.projectId,
                experimentId: this.experimentId,
                experimentName,
                description
            }).then(res => {
                if (res) {
                    this.$message.success('保存成功')
                    this.$emit('update', {
                        experimentId: this.experimentId,
                        experimentName
                    })
                    this.setUpdateExp(Math.random())
                }
            })
        },
        // 修改节点属性之前做校验
        validateUpdateParameter (charCode, paramValue, flag, type) {
            let val = JSON.parse(JSON.stringify(paramValue))
            // 如果是调参类型的需要格式转换下
            if (flag) {
                let {
                    value,
                    tuneRange: {
                        start,
                        end
                    },
                    tuneUdps
                } = val
                let arr = (tuneUdps && tuneUdps.split(',')) || []
                if (type === 'Tuning-Parameter<Double>') {
                    paramValue = {
                        value: value.toString(),
                        tuneRange: {
                            start: start.toString(),
                            end: end.toString()
                        },
                        tuneUdps: arr.map(v => `${v}`)
                    }
                }
                if (type === 'Tuning-Parameter<Long>') {
                    paramValue = {
                        value: value && Number(value),
                        tuneRange: {
                            start: Number(start),
                            end: Number(end)
                        },
                        tuneUdps: arr.map(v => Number(v))
                    }
                }
                val = JSON.stringify(paramValue)
            }
            const params = {
                ...this.params,
                charCode,
                paramValue: val
            }
            this.$post('/experiment/validateUpdateParameter', params).then(res => {
                if (res) {
                    this.updateParameter(params)
                }
            })
        },
        // 修改节点属性参数，获取到的是影响到的节点数据
        updateParameter (params) {
            this.$post('/experiment/updateNodeParameter', params).then(res => {
                res && res.relatedNodes.length > 0 && this.setChangedNodes(Math.random())
            })
        },
        // 获取选择字段弹窗数据
        queryInputFeatureColumns (type, inputColumns) {
            if (inputColumns) {
                this[type].data = inputColumns
                this[type].show = true
                return
            }
            this.$post('/experiment/extend/queryInputFeatureColumns', this.params).then(res => {
                this[type].data = res.inputDataSources[0].schema || []
            }).finally(() => {
                this[type].show = true
            })
        },
        // 获取字面量数据
        getInputDataTableVariable (colsItem) {
            this.$post('/experiment/extend/queryInputDataSourceVariables', this.params).then(res => {
                colsItem.valList = res.inputDataSources || []
            })
        },
        // 获取数据表名
        getTableNames () {
            const parmas = {
                keyword: '',
                projectId: this.projectId
            }
            this.$post('/experiment/catalog/queryDataSourceCatalog', parmas).then(res => {
                if (res) {
                    this.tableNames = this.projectId !== '10000' ? res.publicDataTables.concat(res.projectDataTables) : res.publicDataTables
                }
            })
        },
        // 生成节点属性页信息
        getCreateForm ({ params, relations, tabs }) {
            for (let i = 0; i < tabs.length; i++) {
                this.$set(this.formObj, i, {})
                let arr = tabs[i].controls
                for (let n = 0; n < arr.length; n++) {
                    arr[n]['typeShow'] = true
                    arr[n]['idShow'] = true
                    arr[n]['showRange'] = false
                    this.$set(arr[n], 'disabled', false)
                    let {
                        bindCharCode,
                        controlId,
                        type
                    } = arr[n]
                    if (type === 'inputDataTableVariableDisplay') {
                        this.$set(arr[n], 'valList', this.getInputDataTableVariable(arr[n]) || [])
                    }
                    for (let j = 0; j < params.length; j++) {
                        if (bindCharCode === params[j].charCode) {
                            arr[n] = Object.assign(arr[n], params[j])
                        }
                    }
                    let value = arr[n].paramValue || arr[n].defaultValue
                    if (type === 'mutipleInputColumnSelect') {
                        value = value || []
                    }
                    if (type === 'select') {
                        let temp = []
                        let subArr = arr[n].options
                        for (let j = 0; j < subArr.length; j++) {
                            for (let y = 0; y < relations.length; y++) {
                                if (controlId === relations[y].controlId && subArr[j].value === relations[y].controlValue) {
                                    temp.push(relations[y])
                                }
                            }
                        }
                        arr[n].relations = temp
                    }
                    this.$set(this.formObj[i], bindCharCode, value)
                    if (type === 'tuningParameterValueInput') {
                        this.$set(this.formObj[i][bindCharCode], 'value', value.value || '')
                    }
                    if (type === 'tuningParameterComplexInput') {
                        let {
                            tuneUdps,
                            tuneRange: {
                                start,
                                end
                            }
                        } = value
                        let flag = tuneUdps && Object.prototype.toString.call(tuneUdps) === '[object Array]'
                        this.formObj[i][bindCharCode]['tuneRange']['start'] = start || ''
                        this.formObj[i][bindCharCode]['tuneRange']['end'] = end || ''
                        this.formObj[i][bindCharCode]['tuneUdps'] = (tuneUdps && flag ? tuneUdps.join(',') : tuneUdps) || ''
                    }
                    if (arr[n].type === 'sourceTableNameInput') {
                        this.getTableNames()
                    }
                }
                this.formList[i] = arr
            }
        },
        handleSelectField (type, index, value, isNumber, inputColumns) {
            this.queryInputFeatureColumns(type, inputColumns)
            this.index = index
            if (type === 'multiple') {
                this.multipleVal = value.join(',')
                this.multiple.isNumber = isNumber
            } else {
                this[type].value = value
            }
        },
        // 选择字段弹窗点击确定保存
        handleSave (t, val) {
            this[t].show = false
            let value = ''
            if (t === 'multiple') {
                val = (val && val.split(',')) || []
                value = JSON.stringify(val)
            } else {
                value = val
            }
            const {
                charCode
            } = this.formList[this.activeName][this.index]
            this.formObj[this.activeName][charCode] = val
            this.validateUpdateParameter(charCode, value)
        },
        // 初始化节点属性页信息
        init () {
            this.formList = {}
            this.formObj = {}
            this.activeName = '0'
            this.params = {
                projectId: this.projectId,
                experimentId: this.experimentId,
                nodeId: this.getNodeData.nodeId
            }
            this.loading = true
            this.$post('/experiment/queryUIControls', this.params).then(res => {
                if (res) {
                    const { tabs, params } = res
                    for (let i = 0; i < tabs.length; i++) {
                        const controls = tabs[i].controls
                        for (let n = 0; n < controls.length; n++) {
                            for (let j = 0; j < params.length; j++) {
                                if (controls[n].controlCode === params[j].charCode) {
                                    controls[n].defaultValue = params[j].defaultValue
                                    controls[n].paramValue = params[j].paramValue
                                }
                            }
                        }
                    }
                    this.setNodePropsInfo(res)
                    this.getCreateForm(res)
                }
            }).finally(() => {
                this.loading = false
            })
        },
        // 查询节点日志
        queryNodeErrorLog () {
            const params = {
                projectId: this.projectId,
                experimentId: this.experimentId,
                nodeId: this.getNodeData.nodeId
            }
            this.$post('/experiment/queryNodeErrorLog', params).then(res => {
                this.setErrorLogs(res)
            })
        }
    },
    watch: {
        // 点击节点更新表单信息
        clickNode () {
            this.init()
            this.queryNodeErrorLog()
        }
    }
}
</script>

<style lang="less">
.edit-form {
    height: 100%;
    width: 100%;
    overflow: hidden;

    .my-el-form {
        padding-top: 10px;
    }

    .el-form-item__content {
        width: 100%;
        align-items: center;
    }

    .el-tabs__content {
        height: calc(100% - 40px);
        padding: 0;

        .el-tab-pane {
            height: 100%;
        }
    }

    .scroll-bar {
        padding: 15px 10px;
        height: calc(100% - 40px);
    }

    .el-form-item__label {
        padding: 0;
    }

    .el-tabs {
        border: none;
        height: 100%;
        background: #f5f5f5;
    }

    .is-active {
        background: #f5f5f5 !important;
    }

    .e-p-title {
        text-align: center;
        line-height: 40px;
        border-bottom: 1px solid #e4e7ed;
    }

    .exp-prop {
        font-size: 14px;
        height: 100%;
        width: 100%;
        padding: 0 10px;

        .desc-tip {
            padding-left: 10px;
            font-size: 13px;
        }

        .el-form-item {
            margin-bottom: 0px !important;
        }

        .exp-name-desc {
            display: flex;
            flex-direction: column;
            align-items: flex-start;

            .el-textarea__inner {
                width: 100% !important;
                margin-bottom: 15px;
            }
        }

        .el-textarea__inner {
            width: 260px !important;
        }
    }

    .el-input,
    .el-select,
    .el-range-editor,
    .el-date-editor {
        width: 100% !important;
    }

    .exp-form-item {
        display: flex;
        white-space: nowrap;
    }

}
</style>
